﻿using System;
using System.Threading;
using Eflong.MonitoringLib.Event;

using Eflong.Structure;
using Eflong.Utility;

namespace Eflong.SocketClient
{
    public delegate void DispatchPacketInHandler( object sender , SocketEventArgs e );

    public delegate void DispatchPacketOutHandler( object sender , SocketEventArgs e );

    public delegate void DispatchPacketDealHander( object sender , EventArgs e );

    public delegate void DispatchErrorHandler( object sender , MessageEventArgs e );

    public delegate void DispatchMessageHandler( object sender , MessageEventArgs e );

    public class EventDispatcher
    {
        public EventDispatcher( Client client )
        {
            this.client = client;
        }

        public Client client;

        /// <summary>
        /// 包输入事件处理函数
        /// </summary>
        public event DispatchPacketInHandler onPacketIn;

        /// <summary>
        /// 包输出事件处理函数
        /// </summary>
        public event DispatchPacketOutHandler onPacketOut;

        /// <summary>
        /// 包匹配成功处理函数
        /// </summary>
        public event DispatchPacketDealHander onPacketDeal;

        /// <summary>
        /// 新的处理自动接收的更新包的信息
        /// </summary>
        /// <param name="packet"></param>
        public void DispatchPacketReceived( Packet packet )
        {
            if ( this.client.IsRunning )
            {
                var callback = new WaitCallback( ( p ) =>
                {
                    var aPacket = ( Packet )p;
                    client.PerformUpdatePacket( aPacket );
                } );

                ThreadPool.QueueUserWorkItem( callback , packet );
            }
        }

        /// <summary>
        /// 分派包接受信息
        /// </summary>
        public void DispatchPacketIn( )
        {
            if ( this.client.IsRunning )
            {
                ThreadPool.QueueUserWorkItem( new WaitCallback( this.PacketIn ) , null );
            }
        }

        /// <summary>
        /// 分派包输出信息
        /// </summary>
        public void DispatchPacketOut( )
        {
            if ( this.client.IsRunning )
            {
                ThreadPool.QueueUserWorkItem( new WaitCallback( this.PacketOut ) , null );
            }
        }

        /// <summary>
        /// 分派查询
        /// </summary>
        public void DispatchPacketDeal( )
        {
            if ( this.client.IsRunning )
            {
                ThreadPool.QueueUserWorkItem( new WaitCallback( this.PacketDeal ) , null );
            }
        }

        private void PacketIn( object state )
        {
            try
            {
                if ( this.client.IsRunning && this.onPacketIn != null )
                {
                    onPacketIn( this , new SocketEventArgs( ( uint )SOCKET_ID.WM_APP_RECEIVED ) );
                }
            }
            catch ( Exception ex )
            {
                LogWrapper.Logger.Error( "In PacketIn Error" );
                LogWrapper.Logger.Error( ex.Message );
            }
        }

        private void PacketOut( object state )
        {
            try
            {
                if ( this.client.IsRunning && this.onPacketOut != null )
                {
                    onPacketOut( this , new SocketEventArgs( ( uint )SOCKET_ID.WM_APP_SENDTO ) );
                }
            }
            catch ( Exception ex )
            {
                LogWrapper.Logger.Error( "In PacketOut Error" );
                LogWrapper.Logger.Error( ex.Message );
            }
        }

        private void PacketDeal( object state )
        {
            try
            {
                LogWrapper.Logger.Debug( "PacketAct Deal " + client.name + " : EventDispatcher" );
                if ( this.client.IsRunning && this.onPacketDeal != null )
                {
                    onPacketDeal( this , EventArgs.Empty );
                }
            }
            catch ( Exception ex )
            {
                LogWrapper.Logger.Error( "In PacketDeal Error" );
                LogWrapper.Logger.Error( ex.Message );
            }
        }
    }
}